﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Windows;
using System.Windows.Controls;
using SingleFileUpload.Providers;
using System.Windows.Browser;
using System.Windows.Media;

namespace SingleFileUpload
{
	[ScriptableType]
	public partial class MainPage : UserControl
	{
		private long _maxFileSize = long.MaxValue;

		//private int _maxUpload = 2;
		private string _customParams;
		private string _fileFilter;
		private string _uploadHandlerName;
		private string _uploadHandlerURL;
		private UserFile _theFile;
		private string _fileUniqueIdentifier;

		public event EventHandler MaximumFileSizeReached;
		public event EventHandler SpecialCharacterFound;

		public UserFile TheFile
		{
			get
			{
				return this._theFile;
			}
		}

		public MainPage(IDictionary<string, string> initParams)
		{
			InitializeComponent();

			LoadConfiguration(initParams);

			_theFile = new UserFile();
			_theFile.PropertyChanged+=new System.ComponentModel.PropertyChangedEventHandler(_theFile_PropertyChanged);

			HtmlPage.RegisterScriptableObject("TheFile", TheFile);
			HtmlPage.RegisterScriptableObject("Control", this);

			this.Loaded += new RoutedEventHandler(MainPage_Loaded);
		}

		void _theFile_PropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e)
		{
			if(e.PropertyName.Equals("State"))
			{
				VisualStateManager.GoToState(this, _theFile.State.ToString(), true);
				
				if(_theFile.State == Constants.FileStates.Pause)
				{
					PauseButton.Content = "Img/play.png";
					ToolTipService.SetToolTip(PauseButton, "继续");
				}

				if(_theFile.State == Constants.FileStates.Uploading)
				{
					PauseButton.Content = "Img/pause.png";
					ToolTipService.SetToolTip(PauseButton, "暂停");
				}

				if(_theFile.State == Constants.FileStates.Finished)
				{
					GreyOutText();
				}

				//Show error message when the upload failed:
				if(this._theFile.State == Constants.FileStates.Error)
				{
					ErrorMsgTextBlock.Visibility = Visibility.Visible;

					if(!string.IsNullOrEmpty(this._theFile.ErrorMessage))
					{
						ErrorMsgTextBlock.Text = this._theFile.ErrorMessage;
					}
				}
			}
			else if(e.PropertyName == "Percentage")
			{
				// if the percentage is decreasing, don't use an animation
				if(_theFile.Percentage < PercentageProgress.Value)
				{
					PercentageProgress.Value = _theFile.Percentage;
				}
				else
				{
					sbProgressFrame.Value = _theFile.Percentage;
					sbProgress.Begin();
				}
			}
		}

		void MainPage_Loaded(object sender, RoutedEventArgs e)
		{
			VisualStateManager.GoToState(this, "Empty", false);
		}

		private void DeleteButton_Click(object sender, RoutedEventArgs e)
		{
			//TheFileContainer.Visibility = System.Windows.Visibility.Collapsed;
			//SelectFilesButton.Visibility = System.Windows.Visibility.Visible;
			_theFile.IsDeleted = true;
			VisualStateManager.GoToState(this, "Empty", false);
		}

		private void PauseButton_Click(object sender, RoutedEventArgs e)
		{
			if(_theFile.State == Constants.FileStates.Pause)
			{
				this._theFile.State = Constants.FileStates.Uploading;
				this._theFile.Upload();
			}
			else
			{
				this._theFile.State = Constants.FileStates.Pause;
				this._theFile.PauseUpload();
			}
		}

		private void SelectFilesButton_Click(object sender, RoutedEventArgs e)
		{
			SelectUserFileAndUpload();
		}

		/// <summary>
		/// Open the select file dialog
		/// </summary>
		private void SelectUserFileAndUpload()
		{
			OpenFileDialog ofd = new OpenFileDialog();
			ofd.Multiselect = false;

			try
			{
				//Check the file filter (filter is used to filter file extensions to select, for example only .jpg files)
				if(!string.IsNullOrEmpty(_fileFilter))
				{
					ofd.Filter = _fileFilter;
				}
			}
			catch(ArgumentException ex)
			{
				//User supplied a wrong configuration file
				throw new Exception("错误的文件筛选器配置.", ex);
			}

			if(ofd.ShowDialog() == true)
			{
				if(ofd.File != null && ofd.File.Length > 0)
				{
					var file = ofd.File;

					string fileName = file.Name;

					if(CheckFileName(fileName))
					{
						_theFile = new UserFile();
						_theFile.PropertyChanged += new System.ComponentModel.PropertyChangedEventHandler(_theFile_PropertyChanged);

						_theFile.FileName = file.Name;
						_theFile.FileStream = file.OpenRead();
						_theFile.UIDispatcher = this.Dispatcher;
						_theFile.UploadHandlerURL = _uploadHandlerURL;
						_theFile.InitParams = _customParams;
						_theFile.FileRealName = string.IsNullOrEmpty(_fileUniqueIdentifier) ? file.Name : _fileUniqueIdentifier + "_" + file.Name;

						this.DataContext = _theFile;

						//Check for the file size limit (configurable)
						if(_theFile.FileStream.Length <= _maxFileSize)
						{
							VisualStateManager.GoToState(this, "Uploading", false);

							if(!_theFile.IsDeleted && _theFile.State == Constants.FileStates.Pending)
							{
								_theFile.Upload();
							}
						}
						else
						{
							MessageBox.Show("最大上传文件不能超过: " + (_maxFileSize / 1024 / 1024).ToString() + "MB.", "错误提示", MessageBoxButton.OK);

							if(MaximumFileSizeReached != null)
							{
								MaximumFileSizeReached(this, null);
							}
						}
					}
					else
					{
						MessageBox.Show("文件名含有特殊字符(#,',\"等),无法上传.请去掉这些字符然后再上传!", "错误提示", MessageBoxButton.OK);

						if(SpecialCharacterFound != null)
						{
							SpecialCharacterFound(this, null);
						}
					}
				}
			}
		}

		/// <summary>
		/// Load configuration first from initParams, then from .Config file
		/// </summary>
		/// <param name="initParams"></param>
		private void LoadConfiguration(IDictionary<string, string> initParams)
		{
			string tryTest = string.Empty;

			//Load Custom Config String
			if(initParams.ContainsKey("CustomParam") && !string.IsNullOrEmpty(initParams["CustomParam"]))
			{
				_customParams = initParams["CustomParam"];
			}

			if(initParams.ContainsKey("MaxFileSizeKB") && !string.IsNullOrEmpty(initParams["MaxFileSizeKB"]))
			{
				if(long.TryParse(initParams["MaxFileSizeKB"], out _maxFileSize))
					_maxFileSize = _maxFileSize * 1024;
			}

			if(initParams.ContainsKey("FileFilter") && !string.IsNullOrEmpty(initParams["FileFilter"]))
			{
				_fileFilter = initParams["FileFilter"];
			}

			if(initParams.ContainsKey("UploadHandlerName") && !string.IsNullOrEmpty(initParams["UploadHandlerName"]))
			{
				_uploadHandlerName = initParams["UploadHandlerName"];
			}

			if(initParams.ContainsKey("UploadHandlerURL") && !string.IsNullOrEmpty(initParams["UploadHandlerURL"]))
			{
				_uploadHandlerURL = initParams["UploadHandlerURL"];
			}

			if(initParams.ContainsKey("FileUniqueIdentifier") && !string.IsNullOrEmpty(initParams["FileUniqueIdentifier"]))
			{
				_fileUniqueIdentifier = initParams["FileUniqueIdentifier"];
			}
		}

		/// <summary>
		/// 检查文件名是否含有非法字符
		/// </summary>
		/// <param name="fileName">文件名</param>
		/// <returns></returns>
		private bool CheckFileName(string fileName)
		{
			var result = true;

			foreach(var item in System.IO.Path.GetInvalidPathChars())
			{
				if(fileName.Contains(item))
				{
					result = false;
					break;
				}
			}

			if(fileName.Contains('\'') || fileName.Contains('"') || fileName.Contains('#'))
			{
				result = false;
			}

			return result;
		}

		//private void ShowValidIcon()
		//{
		//  PercentageProgress.Visibility = Visibility.Collapsed;
		//  ValidUploadIcon.Visibility = Visibility.Visible;
		//}

		private void GreyOutText()
		{
			SolidColorBrush grayBrush = new SolidColorBrush(Colors.Gray);

			FileNameTextBlock.Foreground = grayBrush;
			StateTextBlock.Foreground = grayBrush;
			FileSizeTextBlock.Foreground = grayBrush;

		}

	}
}
